package system

import (
	"gove/admin/schemas/req"
	"gove/admin/schemas/resp"
	"gove/core/request"
	"gove/core/response"
	"gove/model/system"
	"time"

	"gorm.io/gorm"
)

type IDictService interface {
	All(allReq req.DictListReq) (res []resp.DictResp, e error)
	List(page request.PageReq, listReq req.DictListReq) (res response.PageResp, e error)
	Detail(id uint) (res resp.DictResp, e error)
	Add(addReq req.DictAddReq) (e error)
	Edit(editReq req.DictEditReq) (e error)
	Del(delReq req.DictDelReq) (e error)
	GroupAll() (res []resp.DictGroupResp, e error)
	GroupList(page request.PageReq, listReq req.DictGroupListReq) (res response.PageResp, e error)
	GroupDetail(id uint) (res resp.DictGroupResp, e error)
	GroupAdd(addReq req.DictGroupAddReq) (e error)
	GroupEdit(editReq req.DictGroupEditReq) (e error)
	GroupDel(delReq req.DictGroupDelReq) (e error)
}

//NewDictService 初始化
func NewDictService(db *gorm.DB) IDictService {
	return &DictService{db: db}
}

//DictService 字典数据服务实现类
type DictService struct {
	db *gorm.DB
}

//All 字典数据所有
func (ddSrv DictService) All(allReq req.DictListReq) (res []resp.DictResp, e error) {
	var dictGroup system.DictGroup
	err := ddSrv.db.Where("dict_type = ? AND is_delete = ?", allReq.DictGroup, 0).Limit(1).First(&dictGroup).Error
	if e = response.CheckErrDBNotRecord(err, "该字典类型不存在！"); e != nil {
		return
	}
	if e = response.CheckErr(err, "All First err"); e != nil {
		return
	}
	ddModel := ddSrv.db.Where("type_id = ? AND is_delete = ?", dictGroup.ID, 0)
	if allReq.Name != "" {
		ddModel = ddModel.Where("name like ?", "%"+allReq.Name+"%")
	}
	if allReq.Value != "" {
		ddModel = ddModel.Where("value like ?", "%"+allReq.Value+"%")
	}
	if allReq.Status >= 0 {
		ddModel = ddModel.Where("status = ?", allReq.Status)
	}
	var dicts []system.Dict
	err = ddModel.Order("id desc").Find(&dicts).Error
	if e = response.CheckErr(err, "All Find err"); e != nil {
		return
	}
	res = []resp.DictResp{}
	response.Copy(&res, dicts)
	return
}

//List 字典数据列表
func (ddSrv DictService) List(page request.PageReq, listReq req.DictListReq) (res response.PageResp, e error) {
	limit := page.PageSize
	offset := page.PageSize * (page.PageNum - 1)
	var dictGroup system.DictGroup
	err := ddSrv.db.Where("dict_type = ? AND is_delete = ?", listReq.DictGroup, 0).Limit(1).First(&dictGroup).Error
	if e = response.CheckErrDBNotRecord(err, "该字典类型不存在！"); e != nil {
		return
	}
	if e = response.CheckErr(err, "List First err"); e != nil {
		return
	}
	ddModel := ddSrv.db.Model(&system.Dict{}).Where("type_id = ? AND is_delete = ?", dictGroup.ID, 0)
	if listReq.Name != "" {
		ddModel = ddModel.Where("name like ?", "%"+listReq.Name+"%")
	}
	if listReq.Value != "" {
		ddModel = ddModel.Where("value like ?", "%"+listReq.Value+"%")
	}
	if listReq.Status >= 0 {
		ddModel = ddModel.Where("status = ?", listReq.Status)
	}
	var count int64
	e = ddModel.Count(&count).Error
	if e = response.CheckErr(err, "List Count err"); e != nil {
		return
	}
	var dds []system.Dict
	err = ddModel.Limit(limit).Offset(offset).Order("id desc").Find(&dds).Error
	if e = response.CheckErr(err, "List Find err"); e != nil {
		return
	}
	dtResp := []resp.DictResp{}
	response.Copy(&dtResp, dds)
	return response.PageResp{
		PageNum:   page.PageNum,
		PageSize: page.PageSize,
		Count:    count,
		Lists:    dtResp,
	}, nil
}

//Detail 字典数据详情
func (ddSrv DictService) Detail(id uint) (res resp.DictResp, e error) {
	var dd system.Dict
	err := ddSrv.db.Where("id = ? AND is_delete = ?", id, 0).Limit(1).First(&dd).Error
	if e = response.CheckErrDBNotRecord(err, "字典数据不存在！"); e != nil {
		return
	}
	if e = response.CheckErr(err, "Detail First err"); e != nil {
		return
	}
	response.Copy(&res, dd)
	return
}

//Add 字典数据新增
func (ddSrv DictService) Add(addReq req.DictAddReq) (e error) {
	if r := ddSrv.db.Where("name = ? AND is_delete = ?", addReq.Name, 0).Limit(1).First(&system.Dict{}); r.RowsAffected > 0 {
		return response.AssertArgumentError.Make("字典数据已存在！")
	}
	var dd system.Dict
	response.Copy(&dd, addReq)
	err := ddSrv.db.Create(&dd).Error
	e = response.CheckErr(err, "Add Create err")
	return
}

//Edit 字典数据编辑
func (ddSrv DictService) Edit(editReq req.DictEditReq) (e error) {
	err := ddSrv.db.Where("id = ? AND is_delete = ?", editReq.ID, 0).Limit(1).First(&system.Dict{}).Error
	if e = response.CheckErrDBNotRecord(err, "字典数据不存在！"); e != nil {
		return
	}
	if e = response.CheckErr(err, "Edit First err"); e != nil {
		return
	}
	if r := ddSrv.db.Where("id != ? AND name = ? AND is_delete = ?", editReq.ID, editReq.Name, 0).Limit(1).First(&system.Dict{}); r.RowsAffected > 0 {
		return response.AssertArgumentError.Make("字典数据已存在！")
	}
	var dd system.Dict
	response.Copy(&dd, editReq)
	err = ddSrv.db.Save(&dd).Error
	e = response.CheckErr(err, "Edit Save err")
	return
}

//Del 字典数据删除
func (ddSrv DictService) Del(delReq req.DictDelReq) (e error) {
	err := ddSrv.db.Model(&system.Dict{}).Where("id IN ?", delReq.Ids).Updates(
		system.Dict{IsDelete: 1, DeleteTime: time.Now().Unix()}).Error
	return response.CheckErr(err, "Del Update err")
}


//All 字典类型所有
func (dtSrv DictService) GroupAll() (res []resp.DictGroupResp, e error) {
	var dictGroups []system.DictGroup
	err := dtSrv.db.Where("is_delete = ?", 0).Order("id desc").Find(&dictGroups).Error
	if e = response.CheckErr(err, "All Find err"); e != nil {
		return
	}
	res = []resp.DictGroupResp{}
	response.Copy(&res, dictGroups)
	return
}

//List 字典类型列表
func (dtSrv DictService) GroupList(page request.PageReq, listReq req.DictGroupListReq) (res response.PageResp, e error) {
	limit := page.PageSize
	offset := page.PageSize * (page.PageNum - 1)
	dtModel := dtSrv.db.Model(&system.DictGroup{}).Where("is_delete = ?", 0)
	if listReq.DictName != "" {
		dtModel = dtModel.Where("dict_name like ?", "%"+listReq.DictName+"%")
	}
	if listReq.DictGroup != "" {
		dtModel = dtModel.Where("dict_type like ?", "%"+listReq.DictGroup+"%")
	}
	if listReq.DictStatus >= 0 {
		dtModel = dtModel.Where("dict_status = ?", listReq.DictStatus)
	}
	var count int64
	err := dtModel.Count(&count).Error
	if e = response.CheckErr(err, "List Count err"); e != nil {
		return
	}
	var dts []system.DictGroup
	err = dtModel.Limit(limit).Offset(offset).Order("id desc").Find(&dts).Error
	if e = response.CheckErr(err, "List Find err"); e != nil {
		return
	}
	dtResp := []resp.DictGroupResp{}
	response.Copy(&dtResp, dts)
	return response.PageResp{
		PageNum:   page.PageNum,
		PageSize: page.PageSize,
		Count:    count,
		Lists:    dtResp,
	}, nil
}

//Detail 字典类型详情
func (dtSrv DictService) GroupDetail(id uint) (res resp.DictGroupResp, e error) {
	var dt system.DictGroup
	err := dtSrv.db.Where("id = ? AND is_delete = ?", id, 0).Limit(1).First(&dt).Error
	if e = response.CheckErrDBNotRecord(err, "字典类型不存在！"); e != nil {
		return
	}
	if e = response.CheckErr(err, "Detail First err"); e != nil {
		return
	}
	response.Copy(&res, dt)
	return
}

//Add 字典类型新增
func (dtSrv DictService) GroupAdd(addReq req.DictGroupAddReq) (e error) {
	if r := dtSrv.db.Where("dict_name = ? AND is_delete = ?", addReq.DictName, 0).Limit(1).First(&system.DictGroup{}); r.RowsAffected > 0 {
		return response.AssertArgumentError.Make("字典名称已存在！")
	}
	if r := dtSrv.db.Where("dict_type = ? AND is_delete = ?", addReq.DictGroup, 0).Limit(1).First(&system.DictGroup{}); r.RowsAffected > 0 {
		return response.AssertArgumentError.Make("字典类型已存在！")
	}
	var dt system.DictGroup
	response.Copy(&dt, addReq)
	err := dtSrv.db.Create(&dt).Error
	e = response.CheckErr(err, "Add Create err")
	return
}

//Edit 字典类型编辑
func (dtSrv DictService) GroupEdit(editReq req.DictGroupEditReq) (e error) {
	err := dtSrv.db.Where("id = ? AND is_delete = ?", editReq.ID, 0).Limit(1).First(&system.DictGroup{}).Error
	if e = response.CheckErrDBNotRecord(err, "字典类型不存在！"); e != nil {
		return
	}
	if e = response.CheckErr(err, "Edit First err"); e != nil {
		return
	}
	if r := dtSrv.db.Where("id != ? AND dict_name = ? AND is_delete = ?", editReq.ID, editReq.DictName, 0).Limit(1).First(&system.DictGroup{}); r.RowsAffected > 0 {
		return response.AssertArgumentError.Make("字典名称已存在！")
	}
	if r := dtSrv.db.Where("id != ? AND dict_type = ? AND is_delete = ?", editReq.ID, editReq.DictGroup, 0).Limit(1).First(&system.DictGroup{}); r.RowsAffected > 0 {
		return response.AssertArgumentError.Make("字典类型已存在！")
	}
	var dt system.DictGroup
	response.Copy(&dt, editReq)
	err = dtSrv.db.Save(&dt).Error
	e = response.CheckErr(err, "Edit Save err")
	return
}

//Del 字典类型删除
func (dtSrv DictService) GroupDel(delReq req.DictGroupDelReq) (e error) {
	err := dtSrv.db.Model(&system.DictGroup{}).Where("id IN ?", delReq.Ids).Updates(
		system.DictGroup{IsDelete: 1, DeleteTime: time.Now().Unix()}).Error
	return response.CheckErr(err, "Del Update err")
}
